﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KaroInterface;

namespace Emerald
{

    public class Action : IAction
    {
        public BoardPoint? OldTilePosition;
        public BoardPoint? OldPiecePosition;
        public BoardPoint NewPiecePosition;
        public EColor? NewPieceColor;
        public bool Set;
        private string dataString;

        public Action(byte xOldTilePos, byte yOldTilePos, byte xOldPiecePos, byte yOldPiecePos, byte xNewPiecePos, byte yNewPiecePos)
        {
            OldTilePosition = new BoardPoint(xOldTilePos, yOldTilePos);
            OldPiecePosition = new BoardPoint(xOldPiecePos, yOldPiecePos);
            NewPiecePosition = new BoardPoint(xNewPiecePos, yNewPiecePos);
            NewPieceColor = null;
            Set = true;
        }

        public Action(BoardPoint OldTilePos, BoardPoint OldPiecePos, BoardPoint NewPiecePos)
        {
            OldTilePosition = OldTilePos;
            OldPiecePosition = OldPiecePos;
            NewPiecePosition = NewPiecePos;
            NewPieceColor = null;
            Set = true;
        }

        public Action(byte xOldPiecePos, byte yOldPiecePos, byte xNewPiecePos, byte yNewPiecePos)
        {
            OldTilePosition = null;
            OldPiecePosition = new BoardPoint(xOldPiecePos, yOldPiecePos);
            NewPiecePosition = new BoardPoint(xNewPiecePos, yNewPiecePos);
            NewPieceColor = null;
            Set = true;
        }

        public Action(BoardPoint oldPiecePos, BoardPoint newPiecePos)
        {
            OldTilePosition = null;
            OldPiecePosition = oldPiecePos;
            NewPiecePosition = newPiecePos;
            NewPieceColor = null;
            Set = true;
        }

        public Action(byte xNewPiecePos, byte yNewPiecePos, EColor color)
        {
            OldTilePosition = null;
            OldPiecePosition = null;
            NewPiecePosition = new BoardPoint(xNewPiecePos, yNewPiecePos);
            NewPieceColor = color;
            Set = true;
        }

        public Action(BoardPoint newPiecePos, EColor color)
        {
            OldTilePosition = null;
            OldPiecePosition = null;
            NewPiecePosition = newPiecePos;
            NewPieceColor = color;
            Set = true;
        }

        public bool MovingTile
        {
            get { return OldTilePosition.HasValue; }
        }

        public bool AddingPiece
        {
            get { return false == OldPiecePosition.HasValue; }
        }

        public bool JumpingPiece
        {
            get { return 2 == (int)OldPiecePosition.Value.EuclidianDistanceTo(NewPiecePosition); }
        }

        public string DataString
        {
            get
            {
                dataString = calculateDataString();
                return dataString;
            }
        }

        private string calculateDataString()
        {
            StringBuilder strBuilder = new StringBuilder();

            int value = 0;

            if (OldTilePosition != null) value += 1;
            if (OldPiecePosition != null) value += 2;

            strBuilder.Append(value + ":");

            if (value == 3)
                strBuilder.AppendFormat("{0,-2},{1,-2};", OldTilePosition.Value.X, OldTilePosition.Value.Y);

            if (value >= 2)
                strBuilder.AppendFormat("{0,-2},{1,-2};", OldPiecePosition.Value.X, OldPiecePosition.Value.Y);

            strBuilder.AppendFormat("{0,-2},{1,-2};", NewPiecePosition.X, NewPiecePosition.Y);

            if (NewPieceColor == null)
            {
                strBuilder.Append("0");
            }
            else if (NewPieceColor == EColor.White)
            {
                strBuilder.Append("1");
            }
            else
            {
                strBuilder.Append("2");
            }

            return strBuilder.ToString();
        }

        public Action(string dataString)
        {
            int value = int.Parse(dataString.Substring(0, 1));
            if (value == 3)
            {
                // new piece/old piece/old tile
                OldTilePosition = new BoardPoint(byte.Parse(dataString.Substring(2, 2)), byte.Parse(dataString.Substring(5, 2)));
                OldPiecePosition = new BoardPoint(byte.Parse(dataString.Substring(8, 2)), byte.Parse(dataString.Substring(11, 2)));
                NewPiecePosition = new BoardPoint(byte.Parse(dataString.Substring(14, 2)), byte.Parse(dataString.Substring(17, 2)));
                NewPieceColor = null;
                Set = true;
            }
            if (value == 2)
            {
                // new piece/old piece 
                OldTilePosition = null;
                OldPiecePosition = new BoardPoint(byte.Parse(dataString.Substring(2, 2)), byte.Parse(dataString.Substring(5, 2)));
                NewPiecePosition = new BoardPoint(byte.Parse(dataString.Substring(8, 2)), byte.Parse(dataString.Substring(11, 2)));
                NewPieceColor = null;
                Set = true;
            }
            if (value == 0)
            {
                // new piece
                OldTilePosition = null;
                OldPiecePosition = null;
                NewPiecePosition = new BoardPoint(byte.Parse(dataString.Substring(2, 2)), byte.Parse(dataString.Substring(5, 2)));
                if (byte.Parse(dataString.Substring(8, 1)) == 1)
                    NewPieceColor = EColor.White;
                else
                    NewPieceColor = EColor.Red;
                Set = true;
            }
        }

        public Action()
        {
            Set = false;
        }

        public override string ToString()
        {
            if (!OldPiecePosition.HasValue)
                return String.Format("Adding piece to {0}{1}", (char)(65 + NewPiecePosition.X), NewPiecePosition.Y);

            String appendix = string.Empty;
            if (OldTilePosition.HasValue)
                appendix = string.Format(" by moving tile from {0}{1}", (char)(65 + OldTilePosition.Value.X), OldTilePosition.Value.Y);
            return String.Format("Moving piece from {0}{1} to {2}{3}{4}", (char)(65 + OldPiecePosition.Value.X), OldPiecePosition.Value.Y, (char)(65 + NewPiecePosition.X), NewPiecePosition.Y, appendix);
        }
    }
}
